/**
 * @author mrdoob / http://mrdoob.com/
 */

import * as THREE from '../../js/threejs/build/three.module.js'

import {ColladaLoader} from '../../js/threejs/jsm/loaders/ColladaLoader.js'
import {DRACOLoader} from '../../js/threejs/jsm/loaders/DRACOLoader.js'
import {FBXLoader} from '../../js/threejs/jsm/loaders/FBXLoader.js'
import {GLTFLoader} from '../../js/threejs/jsm/loaders/GLTFLoader.js'

import {AddObjectCommand} from './commands/AddObjectCommand.js'
import {SetSceneCommand} from './commands/SetSceneCommand.js'

var LoaderRemote = function (editor) {
  let scope = this

  this.texturePath = ''

  this.loadFiles = function (config) {
    let timeout
    let modelFileArr = config['modelFile'].split(',')

    for (const modelFile of modelFileArr) {
      if (modelFile === config.modelFile) {
        clearTimeout(timeout)
      }
      timeout = setTimeout(function () {
        config.modelFile = modelFile
        scope.loadFile(config)
      }, 1000)
    }
  }

  this.onProgress = function (xhr) {
    if (xhr.lengthComputable) {
      editor.signals.objectAllConfiged.active = false
      let size = '(' + Math.floor(xhr.total / 1000).format() + ' KB)'
      let progress = Math.floor((xhr.loaded / event.total) * 100) + '%'
      console.log('%c Loading ==> %s %s', 'color:blue;', size, progress)
    }
  }

  /**
   * 加载远程模型文件
   * @param config 模型配置信息
   */
  this.loadFile = function (config) {
    let url = config['modelFile']
    console.log('加载远程模型文件: ', url)
    editor.config.setKey('autosave', true)
    editor.signals.objectAllConfiged.active = false

    let extension = url.split('.').pop().toLowerCase()
    let loader
    url = editor.BASE_URL + '/sys/common/static/' + url
    switch (extension) {
      case 'dae':
        loader = new ColladaLoader()
        loader.load(
          url,
          (object) => {
            editor.configObj(object, config)
            editor.addObject(object)
          },
          scope.onProgress
        )
        break
      case 'fbx':
        loader = new FBXLoader()
        loader.load(
          url,
          (object) => {
            editor.configObj(object, config)
            editor.addObject(object)
            // editor.execute(new AddObjectCommand(editor, object))
          },
          scope.onProgress
        )
        break
      case 'gltf':
        var dracoLoader = new DRACOLoader()
        dracoLoader.setDecoderPath('../examples/js/libs/draco/gltf/')

        loader = new GLTFLoader()
        loader.setDRACOLoader(dracoLoader)

        loader.load(
          url,
          (object) => {
            editor.configObj(object, config)
            editor.addObject(object)
            // editor.execute(new AddObjectCommand(editor, object))
          },
          scope.onProgress
        )
        break
      case 'json':
      case '3obj':
        var objectLoader = new THREE.ObjectLoader()
        objectLoader.load(
          url,
          function (object) {
            editor.configObj(object, config)
            editor.addObject(object)
            // editor.execute(new AddObjectCommand(editor, object))
          },
          scope.onProgress
        )
        break

      default:
        break
    }
  }

  function handleJSON(data) {
    if (data.metadata === undefined) {
      // 2.0
      data.metadata = {
        type: 'Geometry',
      }
    }

    if (data.metadata.type === undefined) {
      // 3.0
      data.metadata.type = 'Geometry'
    }

    if (data.metadata.formatVersion !== undefined) {
      data.metadata.version = data.metadata.formatVersion
    }

    switch (data.metadata.type.toLowerCase()) {
      case 'buffergeometry':
        var loader = new THREE.BufferGeometryLoader()
        var result = loader.parse(data)

        var mesh = new THREE.Mesh(result)

        editor.execute(new AddObjectCommand(editor, mesh))

        break

      case 'geometry':
        console.error('Loader: "Geometry" is no longer supported.')

        break

      case 'object':
        var loader = new THREE.ObjectLoader()
        loader.setResourcePath(scope.texturePath)

        loader.parse(data, function (result) {
          if (result.isScene) {
            editor.execute(new SetSceneCommand(editor, result))
          } else {
            editor.execute(new AddObjectCommand(editor, result))
          }
        })

        break

      case 'app':
        editor.fromJSON(data)

        break
    }
  }
}

export {LoaderRemote}
